﻿using System;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using Combres;
using Core.Utils;
using ScoutNET.Constraints;
using ScoutNET.Controllers;
using ScoutNET.Routes;
using System.Web.Configuration;
using System.Configuration;

namespace ScoutNET
{
    // Note: For instructions on enabling IIS6 or IIS7 classic mode, 
    // visit http://go.microsoft.com/?LinkId=9394801

    public class MvcApplication : System.Web.HttpApplication
    {
        public static void RegisterRoutes(RouteCollection routes)
        {
            routes.AddCombresRoute("Combres");

            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
            routes.IgnoreRoute("google884930bf56853ce4.html");

            routes.Add(new SubdomainRoute());

            routes.MapRoute(
                "sitemapXML",
                "Sitemap.xml",                                                                                      // URL with parameters
                new { controller = "Sitemap", action = "Sitemap" }                                                  // Parameter defaults
            );

            routes.MapRoute(
                "CSSFile",
                "Global/CSSwitcher.css",                                                                            // URL with parameters
                new { controller = "Global", action = "CSSwitcher" }                                              // Parameter defaults
            );

            routes.MapRoute(
                "JsonFile",
                "Home/FeedReader.json",                                                                            // URL with parameters
                new { controller = "Home", action = "FeedReader" }                                              // Parameter defaults
            );

            routes.MapRoute(
                "ImageStat",                                                                                        // Route name
                "{controller}/{action}/{MailID}/{UserID}.gif",                                                      // URL with parameters
                new { controller = "", action = "", MailID = "", UserID = "" },                                     // Parameter defaults
                new { 
                    MailID = @"^(\{{0,1}([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){12}\}{0,1})$", 
                    UserID = @"^(\{{0,1}([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){12}\}{0,1})$" 
                }
            );

            //Section Pages Routes
            routes.MapRoute(
                "Mail",                                                                                             // Route name
                "{systemName}/{controller}/{action}/{mailId}/{userId}",                                             // URL with parameters
                new { controller = "", action = "", systemName = UrlParameter.Optional, mailId = "", userId = "" },                    // Parameter defaults
                new { systemName = new SectionConstraint(), mailId = @"^\d+$", userId = @"^(\{{0,1}([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){12}\}{0,1})$" }
            );

            routes.MapRoute(
                "SubDomainSectionDefault",
                "{systemName}",                                                                                    // URL with parameters
                new { controller = "Section", action = "Index", systemName = UrlParameter.Optional },                                 // Parameter defaults
                new { systemName = new SectionConstraint() }
            );

            routes.MapRoute(
                "SectionAgenda",                                                                                    // Route name
                "{systemName}/{controller}/{action}/{month}/{year}",                                                // URL with parameters
                new { controller = "", action = "", systemName = UrlParameter.Optional, month = "", year = "" },                       // Parameter defaults
                new { systemName = new SectionConstraint(), month = @"^\d+$", year = @"^\d+$" }
            );

            routes.MapRoute(
                "SectionDetailsWithTitle",                                                                          // Route name
                "{systemName}/{controller}/{action}/{id}/{title}",                                                  // URL with parameters
                new { controller = "", action = "", systemName = UrlParameter.Optional, id = "", title = "" },                         // Parameter defaults
                new { systemName = new SectionConstraint(), id = @"^\d+$" }
            );

            routes.MapRoute(
                "SectionGUID",                                                                                       // Route name
                "{systemName}/{controller}/{action}/{id}",                                                           // URL with parameters
                new { controller = "", action = "", systemName = UrlParameter.Optional, id = "" },                                      // Parameter defaults
                new { systemName = new SectionConstraint(), id = @"^(\{{0,1}([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){12}\}{0,1})$" }
            );
            
            routes.MapRoute(
                "SectionIndex",                                                                                     // Route name
                "{systemName}/{controller}/{action}",                                                               // URL with parameters
                new { controller = "", action = "Index", systemName = UrlParameter.Optional },                                              // Parameter defaults                
                new { systemName = new SectionConstraint() }
            );

            //Pages Routes
            routes.MapRoute(
                "DetailWithID",                                                                                     // Route name
                "{controller}/{action}/{id}/{Title}",                                                               // URL with parameters
                new { controller = "Home", action = "", id = "", Title = "" },                                      // Parameter defaults
                new { id = @"^\d+$" }
            );

            routes.MapRoute(
                "Members",                                                                                          // Route name
                "{controller}/{action}/{id}/{Title}",                                                               // URL with parameters
                new { controller = "Home", action = "", id = "", Title = "" },                                      // Parameter defaults
                new { id = @"^(\{{0,1}([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){12}\}{0,1})$" }
            );

            routes.MapRoute(
                "Default",                                                                                          // Route name
                "{controller}/{action}",                                                                            // URL with parameters
                new { controller = "Home", action = "Index" }                                                       // Parameter defaults
            );

            //Handler route
            routes.MapRoute(
                "ZipFile",                                                                                          // Route name
                "{systemName}/{controller}/{action}/{id}/{title}.zip",                                              // URL with parameters
                new { controller = "", action = "", systemName = UrlParameter.Optional, id = "", title = "" },                         // Parameter defaults
                new { systemName = new SectionConstraint(), id = @"^\d+$" }
            );

            routes.MapRoute(
                "ImageResizer",                                                                                     // Route name
                "{controller}/{action}/{Title}/{id}.jpg",                                                           // URL with parameters
                new { controller = "", action = "", Title = "", id = "" }                                           // Parameter defaults
            );

            routes.MapRoute(
                "NotFound",
                "{*url}",
                new { controller = "Global", action = "Error404" }
            );


        }

        protected void Application_Start(object sender, EventArgs e)
        {
            RegisterRoutes(RouteTable.Routes);

            string appPath = HttpContext.Current.Server.MapPath("/");
            TaskManager.Init(appPath);
        }

        protected void Application_BeginRequest(Object sender, EventArgs e)
        {
            if (!Request.Url.IsLoopback)
            {
                if (!Request.Url.Host.StartsWith("www") && Request.Url.Host.Split('.').Length < 3)
                {
                    UriBuilder builder = new UriBuilder(Request.Url);
                    builder.Host = "www." + Request.Url.Host;
                    Response.StatusCode = 301;
                    Response.AddHeader("Location", builder.ToString());
                    Response.End();
                }
            }
        }
        
        protected void Application_Error(object sender, EventArgs e)
        {
            if (!HttpContext.Current.Request.IsLocal)
            {
                Exception exception = Server.GetLastError();

                Response.Clear();

                HttpException httpException = exception as HttpException;

                RouteData routeData = new RouteData();
                routeData.Values.Add("controller", "Global");

                if (httpException == null)
                {
                    routeData.Values.Add("action", "Index");
                }
                else
                {
                    switch (httpException.GetHttpCode())
                    {
                        case 404:
                            // Page not found.
                            routeData.Values.Add("action", "Error404");
                            break;
                        case 500:
                            // Server error.
                            routeData.Values.Add("action", "Error500");
                            break;
                    }
                }

                // Pass exception details to the target error View.
                routeData.Values.Add("error", exception);

                // Clear the error on server.
                Server.ClearError();

                // Avoid IIS7 getting in the middle
                Response.TrySkipIisCustomErrors = true;

                // Call target Controller and pass the routeData.
                using (GlobalController errorController = new GlobalController())
                {
                    ((IController)errorController).Execute(new RequestContext(new HttpContextWrapper(Context), routeData));
                }
            }
        }

        protected void Application_EndRequest(object sender, EventArgs e)
        {
            foreach (var key in HttpContext.Current.Items.Keys)
            {
                var disposable = HttpContext.Current.Items[key] as IDisposable;

                if (disposable != null)
                {
                    disposable.Dispose();
                }
            }
        }
    }
}